#!/usr/sbin/perl
#                                                                         
#  Copyright (C) 1998, Silicon Graphics, Inc.                             
#  All Rights Reserved.                                                   
#                                                                         
#  UNPUBLISHED -- Rights reserved under the copyright laws of the United  
#  States.  Use of a copyright notice is precautionary only and does not  
#  imply publication or disclosure.                                       
#                                                                         
#  THIS SOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION OF     
#  SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION, DISTRIBUTION, OR 
#  DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN    
#  PERMISSION OF SILICON GRAPHICS, INC.                                   
#                                                                         
#  U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND                               
#  Use, duplication or disclosure by the Government is subject to         
#  restrictions as set forth in FAR 52.227.19(c)(2) or subparagraph       
#  (c)(1)(ii) of the Rights in Technical Data and Computer Software       
#  clause at DFARS 252.227-7013 and/or in similar or successor clauses    
#  in the FAR, or the DOD or NASA FAR Supplement.  Unpublished-- rights   
#  reserved under the copyright laws of the United States.                
#  Contractor/manufacturer is Silicon Graphics, Inc.,                     
#  2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.                 
#

# filesystem
#
# Get all resources for a particular type
# and run the tests against that resource.

require "$LibDiagsPath/constants.pl";
require "$LibDiagsPath/libdiags.pl";
require "$LibDiagsPath/recurse.pl";

sub filesystem {
  local ($machine_name, $resource) = @_;
  local ($this);
  local (@list);
  local ($retv)=$CD_SUCCESS;

  &LogEntry();
  &Verbose("Running resource type %s tests on node %s",
	   $FILESYSTEM, $machine_name);
 
  if ($resource eq "ALL") {
    @list=&GetResFromResType($machine_name, $FILESYSTEM);
    if (scalar(@list) < 1) {
      &Failure("No resources found for type %s",$FILESYSTEM);
      return $CD_FAILURE;
    }
    foreach $this (@list) {
      $retv=&TestFilesystem($machine_name,$this);

      # If the DESTRUCTIVE flag is set ...
      if ($DESTRUCTIVE) {
	if (&Execfilesystem($machine_name,$this) == $CD_FAILURE) {
	      &Failure("Resource %s of resource type %s failed",$this,
		       $FILESYSTEM);
	      $retv=$CD_FAILURE;
	}
      }
      &ExitStatus($retv);
    }
  }else {
    # We have been given the resource name.
    $retv=&TestFilesystem($machine_name, $resource);

    # If the DESTRUCTIVE flag is set ...
    if ($DESTRUCTIVE) {
	if (&Execfilesystem($machine_name,$resource) == $CD_FAILURE) {
	    &Failure("Resource %s of resource type %s failed",$resource,
		     $FILESYSTEM);
	    $retv=$CD_FAILURE;
	}
    }
    &ExitStatus($retv);
  }
  return $retv;

}

sub Execfilesystem {
    local ($node, $resource) = @_;
    local (@depend1, $dependency1, $cnt1);
    local ($retv);
    &LogEntry();

    &Status("Starting resource %s of resource type %s on node %s",
	     $resource,$FILESYSTEM,$node);

    
    # Only execute the destructive tests on this node.
    if (!&OnTheSameNode($node)) {
	&Notice("Can only execute the resource destructive tests on local host");
	&Log("Can only execute the resource destructive tests on local host %s/%s",
	      $this_host, $NodeToHost{$node});
	return $CD_SUCCESS;
    }

    @depend1=&GetResDependency($node,$FILESYSTEM,$resource);
    if (scalar(@depend1) < 1) {
	&Failure("No dependencies returned for resource %s of resource type %s",
		 $resource,$FILESYSTEM);
	return $CD_FAILURE;
    }
    
    # Load all dependencies and start them.
    $cnt1=0;
    foreach $dependency1 (@depend1) {
        # Check that the dependency is set, if so start it
        if ($dependency1=~/$VOLUME/) {
	    $retv=ExecuteScript($node,$depend1[$cnt1+1],$VOLUME,$HA_START);
	    if ( $retv == 0 ) {
		&Failure("Cannot start $FILESYSTEM resource dependency $depend1[$cnt1+1] of type $VOLUME");
		return $CD_FAILURE;
	    }
        }
        $cnt1++;
    }

    # Execute the filesystem resources
    &Status("Executing the $FILESYSTEM resource scripts, I.e. probe, exclusive, start, monitor and stop");
    &Status("Please be patient ...");
    foreach $script (@HA_LIST) {
	$retv=ExecuteScript($node,$resource,$FILESYSTEM,$script);
	if ($retv == 0) {
	    # script failed, exit
	    return $CD_FAILURE;
	}
	# Sleep a while
	sleep(3);
    }
    
    # Stop all dependencies
    $cnt1=0;
    foreach $dependency1 (@depend1) {
        # Check that the dependency is set, if so start it
        if ($dependency1=~/$VOLUME/) {
	    $retv=ExecuteScript($node,$depend1[$cnt1+1],$VOLUME,$HA_STOP);
	    if ( $retv == 0 ) {
		&Failure("Cannot stop $FILESYSTEM resource dependency $depend1[$cnt1+1] of type $VOLUME");
		return $CD_FAILURE;
	    }
        }
        $cnt1++;
    }
    return $CD_SUCCESS;
}

# TestFilesystem
# The resource test has three parts
#   1) Check the resource parameters.
#   2) If the resource has dependencies check them.

sub TestFilesystem {
  local ($machine, $resource) = @_;
  local ($retv);
  local ($volume, $options, $level);
  local (@parameters,@depend);

  $retv=$CD_SUCCESS;

  &LogEntry();
  &Status("Testing resource %s of resource type %s on node %s",
	   $resource,$FILESYSTEM,$machine_name);
  
  # Get the resource parameter list.
  @parameters=&GetResParameters($machine,$FILESYSTEM,$resource);
  if (scalar(@parameters) < 1 ) {
    &Failure("No parameters found for resource %s of resource type %s",
	     $resource,$FILESYSTEM);
    return $CD_FAILURE;
  }

  if (@parameters[0] < 0){
    &Failure("No parameters found for resource %s of type %s",
	     $resource,$FILESYSTEM);
    return $CD_FAILURE;
  }

  if (($volume=&pulloff("volume-name",@parameters)) eq "") {
    &Failure("%s resource %s does not have the %s parameter set",
	     $FILEYSTEM,$resource,"volume-name");
    $retv=$CD_FAILURE;
  }

  if (($options=&pulloff("mount-options",@parameters)) eq "") {
    &Failure("%s resource %s does not have the %s parameter set",
	     $FILESYSTEM,$resource,"mount-options");
    $retv=$CD_FAILURE;
  }

  # PV 676533 - Diags, scripts warn that filesystem does not 
  #             have monitoring-level set.
  if (($level=&pulloff("monitoring-level",@parameters)) eq "") {
    &Notice("Default monitoring-level is assumed for the %s resource of resource type %s",
	    $resource,$FILESYSTEM);
  }

  # Check the volume dependency, should be the same as the $volume
  @depend=&GetResDependency($machine,$FILESYSTEM,$resource);

  if (scalar(@depend) < 1) {
     &Failure("No dependencies returned for resource %s of resource type %s",
	     $resource,$FILESYTEM);
     return $CD_FAILURE;
  }

  if (@depend[0] < 0){
    &Failure("No dependencies found for resource %s of resource type %s",
	     $resource,$FILESYSTEM);
    return $CD_FAILURE;
  }
  
  if (($depend[0] eq "$VOLUME") && ($depend[1] eq " ")){
    &Failure("Resource %s does not have the %s dependency set",
	     $resource,$VOLUME);
    $retv=$CD_FAILURE;
  }
     
  if ($depend[1] ne $volume) {
    &Failure("%s dependency %s is inconsistent with parameter %s",
	     $resource, $depend[1], $volume);
    $retv=$CD_FAILURE;
  }
  
  # Check that the found point exists in the node/host in question
  $cmd="file $resource";
  @output=&rsh($machine,$cmd);
  if ($RSH_ERRNO != 0) {
      $retv=$CD_FAILURE;
  }
  foreach $line (@output) {
      if ($line =~ /.*(No such file or directory)/) {
	  &Failure("Resource %s of resource type %s does not have system mount point.",
		   $resource,$FILESYSTEM);
	  $retv=$CD_FAILURE;
      }
  }

  return $retv;
}
